package gui;

import entity.Score;
import entity.Student;
import service.ScoreAnalysis;
import service.ScoreManager;
import service.StudentManager;

import javax.swing.*;
import javax.swing.table.DefaultTableModel;
import java.awt.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 统计分析面板
 */
public class StatisticsPanel extends JPanel {
    private final ScoreManager scoreManager;
    private final StudentManager studentManager;
    
    // UI组件
    private JTable rankingTable;
    private DefaultTableModel rankingTableModel;
    private JPanel averagePanel;
    private JPanel distributionPanel;
    private JTabbedPane tabbedPane;
    private JPanel chartPanel; // 新增图表面板
    
    /**
     * 构造函数
     */
    public StatisticsPanel(ScoreManager scoreManager, StudentManager studentManager) {
        this.scoreManager = scoreManager;
        this.studentManager = studentManager;
        initUI();
    }
    
    /**
     * 初始化UI
     */
    private void initUI() {
        setLayout(new BorderLayout(10, 10));
        setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
        
        // 创建选项卡面板
        tabbedPane = new JTabbedPane();
        
        // 创建平均分面板
        averagePanel = createAveragePanel();
        
        // 创建排名面板
        JPanel rankingPanel = createRankingPanel();
        
        // 创建分布分析面板
        distributionPanel = createDistributionPanel();
        
        // 创建图表面板
        chartPanel = createChartPanel();
        
        // 添加选项卡
        tabbedPane.addTab("班级平均分", averagePanel);
        tabbedPane.addTab("成绩排名", rankingPanel);
        tabbedPane.addTab("成绩分布", distributionPanel);
        tabbedPane.addTab("成绩图表", chartPanel);
        
        // 添加组件到面板
        add(tabbedPane, BorderLayout.CENTER);
        
        // 刷新数据
        refreshData();
    }
    
    /**
     * 创建平均分面板
     */
    private JPanel createAveragePanel() {
        JPanel panel = new JPanel();
        panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
        panel.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
        
        // 将在refreshData中填充内容
        return panel;
    }
    
    /**
     * 创建排名面板
     */
    private JPanel createRankingPanel() {
        JPanel panel = new JPanel(new BorderLayout(10, 10));
        panel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
        
        // 表格列名
        String[] columnNames = {"排名", "学号", "姓名", "语文", "数学", "英语", "总分"};
        
        // 创建表格模型
        rankingTableModel = new DefaultTableModel(columnNames, 0) {
            @Override
            public boolean isCellEditable(int row, int column) {
                return false; // 设置表格不可编辑
            }
        };
        
        // 创建表格
        rankingTable = new JTable(rankingTableModel);
        rankingTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        rankingTable.getTableHeader().setReorderingAllowed(false);
        
        // 添加表格到面板
        panel.add(new JScrollPane(rankingTable), BorderLayout.CENTER);
        
        return panel;
    }
    
    /**
     * 创建分布分析面板
     */
    private JPanel createDistributionPanel() {
        JPanel panel = new JPanel();
        panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
        panel.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
        
        // 将在refreshData中填充内容
        return panel;
    }
    
    /**
     * 创建图表面板
     */
    private JPanel createChartPanel() {
        JPanel panel = new JPanel(new BorderLayout());
        panel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
        
        // 添加说明标签
        JLabel infoLabel = new JLabel("成绩分布图表", JLabel.CENTER);
        infoLabel.setFont(new Font("微软雅黑", Font.BOLD, 16));
        panel.add(infoLabel, BorderLayout.NORTH);
        
        // 创建图表显示面板
        JPanel chartDisplayPanel = new JPanel() {
            @Override
            protected void paintComponent(Graphics g) {
                super.paintComponent(g);
                drawChart(g);
            }
        };
        chartDisplayPanel.setBackground(Color.WHITE);
        panel.add(new JScrollPane(chartDisplayPanel), BorderLayout.CENTER);
        
        return panel;
    }
    
    /**
     * 绘制图表
     */
    private void drawChart(Graphics g) {
        if (scoreManager.getScores().isEmpty()) {
            return;
        }
        
        // 创建成绩分析对象
        ScoreAnalysis scoreAnalysis = new ScoreAnalysis(scoreManager.getScores());
        
        // 获取各科目成绩分布
        Map<String, Integer> chineseDist = scoreAnalysis.getScoreDistribution("chinese");
        Map<String, Integer> mathDist = scoreAnalysis.getScoreDistribution("math");
        Map<String, Integer> englishDist = scoreAnalysis.getScoreDistribution("english");
        
        // 设置图表参数
        int width = 600;
        int height = 400;
        int barWidth = 50;
        int barSpacing = 20;
        int startX = 50;
        int startY = 350;
        int maxValue = Math.max(1, getMaxValue(chineseDist, mathDist, englishDist));
        
        // 绘制坐标轴
        g.setColor(Color.BLACK);
        g.drawLine(startX, startY, startX, 50); // Y轴
        g.drawLine(startX, startY, startX + 400, startY); // X轴
        
        // 绘制标题
        g.setFont(new Font("微软雅黑", Font.BOLD, 16));
        g.drawString("各科目成绩分布图", startX + 100, 30);
        
        // 绘制图例
        g.setColor(Color.RED);
        g.fillRect(startX + 350, 60, 15, 15);
        g.setColor(Color.BLACK);
        g.drawString("语文", startX + 370, 72);
        
        g.setColor(Color.BLUE);
        g.fillRect(startX + 350, 80, 15, 15);
        g.setColor(Color.BLACK);
        g.drawString("数学", startX + 370, 92);
        
        g.setColor(Color.GREEN);
        g.fillRect(startX + 350, 100, 15, 15);
        g.setColor(Color.BLACK);
        g.drawString("英语", startX + 370, 112);
        
        // 绘制柱状图
        String[] levels = {"优秀", "良好", "中等", "及格", "不及格"};
        Color[] colors = {Color.RED, Color.BLUE, Color.GREEN};
        
        for (int i = 0; i < levels.length; i++) {
            int x = startX + i * (barWidth * 3 + barSpacing) + barSpacing;
            
            // 语文成绩
            int chineseHeight = (int) (chineseDist.getOrDefault(levels[i], 0) * 200.0 / maxValue);
            g.setColor(Color.RED);
            g.fillRect(x, startY - chineseHeight, barWidth, chineseHeight);
            g.setColor(Color.BLACK);
            g.drawRect(x, startY - chineseHeight, barWidth, chineseHeight);
            g.drawString(String.valueOf(chineseDist.getOrDefault(levels[i], 0)), x + barWidth/2 - 5, startY - chineseHeight - 5);
            
            // 数学成绩
            int mathHeight = (int) (mathDist.getOrDefault(levels[i], 0) * 200.0 / maxValue);
            g.setColor(Color.BLUE);
            g.fillRect(x + barWidth, startY - mathHeight, barWidth, mathHeight);
            g.setColor(Color.BLACK);
            g.drawRect(x + barWidth, startY - mathHeight, barWidth, mathHeight);
            g.drawString(String.valueOf(mathDist.getOrDefault(levels[i], 0)), x + barWidth + barWidth/2 - 5, startY - mathHeight - 5);
            
            // 英语成绩
            int englishHeight = (int) (englishDist.getOrDefault(levels[i], 0) * 200.0 / maxValue);
            g.setColor(Color.GREEN);
            g.fillRect(x + barWidth * 2, startY - englishHeight, barWidth, englishHeight);
            g.setColor(Color.BLACK);
            g.drawRect(x + barWidth * 2, startY - englishHeight, barWidth, englishHeight);
            g.drawString(String.valueOf(englishDist.getOrDefault(levels[i], 0)), x + barWidth * 2 + barWidth/2 - 5, startY - englishHeight - 5);
            
            // 绘制标签
            g.setColor(Color.BLACK);
            g.drawString(levels[i], x + barWidth, startY + 20);
        }
    }
    
    /**
     * 获取最大值
     */
    private int getMaxValue(Map<String, Integer>... maps) {
        int max = 0;
        for (Map<String, Integer> map : maps) {
            for (int value : map.values()) {
                if (value > max) {
                    max = value;
                }
            }
        }
        return max;
    }
    
    /**
     * 刷新数据
     */
    public void refreshData() {
        // 创建成绩分析对象
        ScoreAnalysis scoreAnalysis = new ScoreAnalysis(scoreManager.getScores());
        
        // 更新平均分面板
        updateAveragePanel(scoreAnalysis);
        
        // 更新排名表格
        updateRankingTable(scoreAnalysis);
        
        // 更新分布分析面板
        updateDistributionPanel(scoreAnalysis);
        
        // 刷新图表面板
        chartPanel.repaint();
    }
    
    /**
     * 更新平均分面板
     */
    private void updateAveragePanel(ScoreAnalysis scoreAnalysis) {
        // 清空面板
        averagePanel.removeAll();
        
        // 计算平均分
        double chineseAvg = scoreAnalysis.averageChinese();
        double mathAvg = scoreAnalysis.averageMath();
        double englishAvg = scoreAnalysis.averageEnglish();
        double totalAvg = scoreAnalysis.averageTotal();
        double overallAvg = scoreAnalysis.averageOverall();
        
        // 创建标签
        JLabel titleLabel = new JLabel("班级平均成绩统计", JLabel.CENTER);
        titleLabel.setFont(new Font("微软雅黑", Font.BOLD, 18));
        titleLabel.setAlignmentX(Component.CENTER_ALIGNMENT);
        
        JLabel chineseLabel = new JLabel(String.format("语文平均分: %.2f", chineseAvg));
        chineseLabel.setFont(new Font("微软雅黑", Font.PLAIN, 16));
        chineseLabel.setAlignmentX(Component.CENTER_ALIGNMENT);
        
        JLabel mathLabel = new JLabel(String.format("数学平均分: %.2f", mathAvg));
        mathLabel.setFont(new Font("微软雅黑", Font.PLAIN, 16));
        mathLabel.setAlignmentX(Component.CENTER_ALIGNMENT);
        
        JLabel englishLabel = new JLabel(String.format("英语平均分: %.2f", englishAvg));
        englishLabel.setFont(new Font("微软雅黑", Font.PLAIN, 16));
        englishLabel.setAlignmentX(Component.CENTER_ALIGNMENT);
        
        JLabel totalLabel = new JLabel(String.format("总分平均分: %.2f", totalAvg));
        totalLabel.setFont(new Font("微软雅黑", Font.PLAIN, 16));
        totalLabel.setAlignmentX(Component.CENTER_ALIGNMENT);
        
        JLabel overallLabel = new JLabel(String.format("总体平均分: %.2f", overallAvg));
        overallLabel.setFont(new Font("微软雅黑", Font.BOLD, 16));
        overallLabel.setAlignmentX(Component.CENTER_ALIGNMENT);
        
        // 获取最高分信息
        Map<String, Double> topScores = scoreAnalysis.getSubjectTopScores();
        JLabel topChineseLabel = new JLabel(String.format("语文最高分: %.2f", topScores.getOrDefault("chinese", 0.0)));
        topChineseLabel.setFont(new Font("微软雅黑", Font.PLAIN, 14));
        topChineseLabel.setAlignmentX(Component.CENTER_ALIGNMENT);
        
        JLabel topMathLabel = new JLabel(String.format("数学最高分: %.2f", topScores.getOrDefault("math", 0.0)));
        topMathLabel.setFont(new Font("微软雅黑", Font.PLAIN, 14));
        topMathLabel.setAlignmentX(Component.CENTER_ALIGNMENT);
        
        JLabel topEnglishLabel = new JLabel(String.format("英语最高分: %.2f", topScores.getOrDefault("english", 0.0)));
        topEnglishLabel.setFont(new Font("微软雅黑", Font.PLAIN, 14));
        topEnglishLabel.setAlignmentX(Component.CENTER_ALIGNMENT);
        
        // 添加组件到面板
        averagePanel.add(Box.createVerticalGlue());
        averagePanel.add(titleLabel);
        averagePanel.add(Box.createVerticalStrut(20));
        averagePanel.add(chineseLabel);
        averagePanel.add(Box.createVerticalStrut(10));
        averagePanel.add(mathLabel);
        averagePanel.add(Box.createVerticalStrut(10));
        averagePanel.add(englishLabel);
        averagePanel.add(Box.createVerticalStrut(10));
        averagePanel.add(totalLabel);
        averagePanel.add(Box.createVerticalStrut(20));
        averagePanel.add(overallLabel);
        averagePanel.add(Box.createVerticalStrut(20));
        averagePanel.add(new JLabel("各科目最高分:", JLabel.CENTER));
        averagePanel.add(topChineseLabel);
        averagePanel.add(Box.createVerticalStrut(5));
        averagePanel.add(topMathLabel);
        averagePanel.add(Box.createVerticalStrut(5));
        averagePanel.add(topEnglishLabel);
        averagePanel.add(Box.createVerticalGlue());
        
        // 刷新面板
        averagePanel.revalidate();
        averagePanel.repaint();
    }
    
    /**
     * 更新排名表格
     */
    private void updateRankingTable(ScoreAnalysis scoreAnalysis) {
        // 清空表格
        rankingTableModel.setRowCount(0);
        
        // 获取成绩和学生信息
        Map<String, Score> scores = scoreManager.getScores();
        Map<String, Student> students = studentManager.getStudentMap();
        
        if (scores.isEmpty()) {
            return;
        }
        
        // 创建成绩列表并排序
        List<Score> scoreList = new ArrayList<>(scores.values());
        scoreList.sort((s1, s2) -> Double.compare(s2.getTotalScore(), s1.getTotalScore()));
        
        // 添加数据到表格
        int rank = 1;
        for (Score score : scoreList) {
            String studentId = score.getStudentId();
            String studentName = students.containsKey(studentId) ? students.get(studentId).getName() : "未知";
            
            Object[] rowData = {
                    rank++,
                    studentId,
                    studentName,
                    score.getChinese(),
                    score.getMath(),
                    score.getEnglish(),
                    score.getTotalScore()
            };
            rankingTableModel.addRow(rowData);
        }
    }
    
    /**
     * 更新分布分析面板
     */
    private void updateDistributionPanel(ScoreAnalysis scoreAnalysis) {
        // 清空面板
        distributionPanel.removeAll();
        
        // 获取成绩分布
        Map<String, Integer> chineseDistribution = scoreAnalysis.getScoreDistribution("chinese");
        Map<String, Integer> mathDistribution = scoreAnalysis.getScoreDistribution("math");
        Map<String, Integer> englishDistribution = scoreAnalysis.getScoreDistribution("english");
        
        // 创建标签
        JLabel titleLabel = new JLabel("成绩分布统计", JLabel.CENTER);
        titleLabel.setFont(new Font("微软雅黑", Font.BOLD, 18));
        titleLabel.setAlignmentX(Component.CENTER_ALIGNMENT);
        
        // 创建分布面板
        JPanel chinesePanel = createDistributionSubPanel("语文成绩分布", chineseDistribution);
        JPanel mathPanel = createDistributionSubPanel("数学成绩分布", mathDistribution);
        JPanel englishPanel = createDistributionSubPanel("英语成绩分布", englishDistribution);
        
        // 添加组件到面板
        distributionPanel.add(titleLabel);
        distributionPanel.add(Box.createVerticalStrut(20));
        distributionPanel.add(chinesePanel);
        distributionPanel.add(Box.createVerticalStrut(20));
        distributionPanel.add(mathPanel);
        distributionPanel.add(Box.createVerticalStrut(20));
        distributionPanel.add(englishPanel);
        
        // 刷新面板
        distributionPanel.revalidate();
        distributionPanel.repaint();
    }
    
    /**
     * 创建分布子面板
     */
    private JPanel createDistributionSubPanel(String title, Map<String, Integer> distribution) {
        JPanel panel = new JPanel();
        panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
        panel.setBorder(BorderFactory.createTitledBorder(title));
        
        // 创建标签
        JLabel excellentLabel = new JLabel(String.format("优秀(90-100分): %d人", distribution.getOrDefault("优秀", 0)));
        JLabel goodLabel = new JLabel(String.format("良好(80-89分): %d人", distribution.getOrDefault("良好", 0)));
        JLabel averageLabel = new JLabel(String.format("中等(70-79分): %d人", distribution.getOrDefault("中等", 0)));
        JLabel passLabel = new JLabel(String.format("及格(60-69分): %d人", distribution.getOrDefault("及格", 0)));
        JLabel failLabel = new JLabel(String.format("不及格(0-59分): %d人", distribution.getOrDefault("不及格", 0)));
        
        // 添加组件到面板
        panel.add(excellentLabel);
        panel.add(Box.createVerticalStrut(5));
        panel.add(goodLabel);
        panel.add(Box.createVerticalStrut(5));
        panel.add(averageLabel);
        panel.add(Box.createVerticalStrut(5));
        panel.add(passLabel);
        panel.add(Box.createVerticalStrut(5));
        panel.add(failLabel);
        
        return panel;
    }
    
    /**
     * 更新图表面板
     */
    private void updateChartPanel(ScoreAnalysis scoreAnalysis) {
        // 清空面板
        chartPanel.removeAll();
        
        // 将在refreshData中填充内容
    }
}